/*
 *
 * Paros and its related class files.
 * 
 * Paros is an HTTP/HTTPS proxy for assessing web application security.
 * Copyright (C) 2003-2004 Chinotec Technologies Company
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the Clarified Artistic License
 * as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * Clarified Artistic License for more details.
 * 
 * You should have received a copy of the Clarified Artistic License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package org.parosproxy.paros.core.scanner;

import java.util.Vector;
import java.util.regex.Pattern;

import org.parosproxy.paros.network.HttpMessage;

/**
 * 
 * To change the template for this generated type comment go to Window -
 * Preferences - Java - Code Generation - Code and Comments
 */
abstract public class VariantAbstractQuery implements Variant {

	private static Pattern staticPatternParam = Pattern.compile("&",
			Pattern.CASE_INSENSITIVE);

	private Vector<NameValuePair> listParam = new Vector<NameValuePair>();

	public VariantAbstractQuery() {

	}

	abstract protected void buildMessage(HttpMessage msg, String query);

	/**
	 * Return encoded mutate of the value. To be overriden by subclass.
	 * 
	 * @param msg
	 * @param value
	 * @return Encoded value
	 */
	protected String getEncodedValue(HttpMessage msg, String value) {
		return value;
	}

	protected void parse(String params) {

		if (params == null || params.equals("")) {
			return;
		}

		String[] keyValue = staticPatternParam.split(params);
		String key = null;
		String value = null;
		int pos = 0;
		for (int i = 0; i < keyValue.length; i++) {
			key = null;
			value = null;
			pos = keyValue[i].indexOf('=');
			try {
				if (pos > 0) {
					key = keyValue[i].substring(0, pos);
					value = keyValue[i].substring(pos + 1);
				} else {
					key = keyValue[i];
					value = null;

				}
				listParam.add(new NameValuePair(key, value, i));

			} catch (Exception e) {
			}
		}

	}

	public Vector<NameValuePair> getParamList() {
		return listParam;
	}

	/**
	 * If name and value = null, not to append entire paramter.
	 */
	public String setParameter(HttpMessage msg, NameValuePair originalPair,
			String name, String value) {

		StringBuffer sb = new StringBuffer();
		NameValuePair pair = null;
		boolean isAppended = false;
		for (int i = 0; i < getParamList().size(); i++) {
			pair = (NameValuePair) getParamList().get(i);
			if (i == originalPair.getPosition()) {
				String encodedValue = getEncodedValue(msg, value);
				isAppended = paramAppend(sb, name, encodedValue);

			} else {
				isAppended = paramAppend(sb, pair.getName(), pair.getValue());

			}

			if (isAppended && i < getParamList().size() - 1) {
				sb.append('&');
			}
		}

		String query = sb.toString();
		buildMessage(msg, query);
		return query;
	}

	/**
	 * Set the name value pair into the StringBuffer. If both name and value is
	 * null, not to append whole paramter.
	 * 
	 * @param sb
	 * @param name
	 *            Null = not to append parameter.
	 * @param value
	 *            null = not to append parameter value.
	 * @return true = paretmer changed.
	 */
	private boolean paramAppend(StringBuffer sb, String name, String value) {
		boolean isEdited = false;
		if (name != null) {
			sb.append(name);
			isEdited = true;
		}
		if (value != null) {
			sb.append('=');
			sb.append(value);
			isEdited = true;
		}
		return isEdited;
	}

}
